<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>手写Promise</title>
</head>

<body>
  <h2>链式编程-处理返回值和异常</h2>
  <script>
    // 执行异步任务
    function runAsynctask(callback) {
      if (typeof queueMicrotask === 'function') {
        queueMicrotask(callback)
      } else if (typeof MutationObserver === 'function') {
        const obs = new MutationObserver(callback)
        const divNode = document.createElement('div')
        obs.observe(divNode, { childList: true })
        divNode.innerText = 'itheima666'
      } else {
        setTimeout(callback, 0)
      }
    }

    /**
     * 链式编程-处理异常和普通内容(fulfilled状态)
     *  1. 返回新Promise实例
     *  2. 获取返回值
     *    2.1 处理返回值
     *    2.2 处理异常
    */
    const PENDING = 'pending'
    const FULFILLED = 'fulfilled'
    const REJECTED = 'rejected'
    class HMPromise {
      // 状态
      state = PENDING
      // 原因
      result = undefined
      // 回调函数数组
      #handlers = [] // [{onFulfilled,onRejected}...]

      // 构造函数
      constructor(func) {
        // pending->fulfilled
        const resolve = (result) => {
          if (this.state === PENDING) {
            this.state = FULFILLED
            this.result = result
            this.#handlers.forEach(({ onFulfilled }) => {
              onFulfilled(this.result)
            })
          }
        }
        // pending->rejected
        const reject = (result) => {
          if (this.state === PENDING) {
            this.state = REJECTED
            this.result = result
            this.#handlers.forEach(({ onRejected }) => {
              onRejected(this.result)
            })
          }
        }
        func(resolve, reject)
      }

      // then方法
      // 1. 返回新Promise实例
      // 2. 获取返回值
      //    2.1 处理返回值
      //    2.2 处理异常
      then(onFulfilled, onRejected) {
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : x => x
        onRejected = typeof onRejected === 'function' ? onRejected : x => { throw x }

        // 1. 返回新Promise实例
        const p2 = new HMPromise((resolve, reject) => {
          if (this.state === FULFILLED) {
            runAsynctask(() => {
              // 2. 获取返回值
              try {
                const x = onFulfilled(this.result)
                // console.log('x:', x)
                // 2.1 处理返回值
                resolve(x)
              } catch (error) {
                // 2.2 处理异常
                // console.log('捕获异常:', error)
                reject(error)
              }
            })
          }
          else if (this.state === REJECTED) {
            runAsynctask(() => {
              onRejected(this.result)
            })
          }
          else if (this.state === PENDING) {
            this.#handlers.push({
              onFulfilled: () => {
                runAsynctask(() => {
                  onFulfilled(this.result)
                })
              }, onRejected: () => {
                runAsynctask(() => {
                  onRejected(this.result)
                })
              }
            })
          }

        })

        return p2
      }
    }


    // ------------- 测试代码 -------------
    const p = new HMPromise((resolve, reject) => {
      resolve(1)
    })
    p.then(res => {
      console.log('p1:', res)
      throw 'throw-error'
      return 2
    }).then(res => {
      console.log('p2:', res)
    }, err => {
      console.log('p2:', err)
    })
















  </script>
</body>

</html>